/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.gov.cemaden.library.dao.produto;

import br.gov.cemaden.library.dao.GenericDao;
import br.gov.cemaden.library.interfaces.produto.ProdutoInterface;
import br.gov.cemaden.library.model.produto.Produto;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author paulo.dias
 */
public class ProdutoDao extends GenericDao implements ProdutoInterface {

    private Session session;

    public ProdutoDao(Session session) {
        this.session = session;
    }

    @Override
    public List<Produto> findAll() {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findAll");
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findAll: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public Produto findById(Long id) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        Produto produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findById").setParameter("id", id);
            produto = (Produto) query.uniqueResult();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findById: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByDatahoracadastro(Date datahoracadastro) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByDatahoracadastro").setParameter("datahoracadastro", datahoracadastro);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByDatahoracadastro: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByFimdaoperacao(Date fimdaoperacao) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByFimdaoperacao").setParameter("fimdaoperacao", fimdaoperacao);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByFimdaoperacao: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByIniciodaoperacao(Date iniciodaoperacao) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByIniciodaoperacao").setParameter("iniciodaoperacao", iniciodaoperacao);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByIniciodaoperacao: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByStatus(Integer status) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByStatus").setParameter("status", status);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByStatus: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByAtuais(Integer atuais) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByAtuais").setParameter("atuais", atuais);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByAtuais: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByFrequencia(Integer frequencia) {
        //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Produto> produto = null;
        try {
            Query query = session.getNamedQuery("Produto.findByFrequencia").setParameter("frequencia", frequencia);
            produto = (List<Produto>) query.list();
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
            System.out.println("Erro no ProdutoDao.findByFrequencia: " + e.getMessage() + " - Causa: " + e.getCause());
            throw new HibernateException(e);
        }
        return produto;
    }

    @Override
    public List<Produto> findByBetween(float inicio, float fim, Long id) {
        List<Produto> list = null;
        try {
            //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx = session.beginTransaction();
            String hql;
            if (id == null) {
                hql = "SELECT * FROM produto.prd_produto ORDER BY id ASC LIMIT " + inicio + " OFFSET " + fim;
            } else {
                hql = "SELECT * FROM produto.prd_produto WHERE id = " + id;
            }

            list = session.createSQLQuery(hql).addEntity(Produto.class).list();
            session.flush();
            tx.commit();
        } catch (HibernateException e) {
            System.out.println("Erro no ProdutoDao.findByBetween() - " + e.toString());
            throw new HibernateException(e);
        }
        return list;
    }

    //metodo para saber o total de linhas registrada na tabela
    public BigInteger totalCadastro() {
        BigInteger total = null;
        try {
            //Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx = session.beginTransaction();
            String hql = "SELECT COUNT(*) as total FROM produto.prd_produto";
            Query query = session.createSQLQuery(hql);
            total = (BigInteger) query.uniqueResult();
            session.flush();
            tx.commit();

        } catch (HibernateException e) {
            System.out.println("Erro no ProdutoDao.totalCadastro() - " + e.toString());
            throw new HibernateException(e);
        }
        return total;
    }    

    @Override
    public void insert(Produto produto) {
        try {
            saveOrUpdate(this.session, produto);
        } catch (Exception ex) {
            Logger.getLogger(ProdutoDao.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void update(Produto produto) {
        try {
            saveOrUpdate(this.session, produto);
        } catch (Exception ex) {
            Logger.getLogger(ProdutoDao.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void delete(Produto produto) {
        try {
            remove(this.session, produto);
        } catch (Exception ex) {
            Logger.getLogger(ProdutoDao.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
